package com.hong.spring.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.hong.spring.dao.UserMapper;
import com.hong.spring.entity.User;
import com.hong.spring.entity.ao.UserAO;
import com.hong.spring.service.IUserService;
import com.hong.spring.utils.DataResponse;
import lombok.extern.log4j.Log4j2;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Auther: csh
 * @Date: 2020/8/18 15:16
 * @Description:用户实现
 */
@Service
@Log4j2
public class UserServiceImpl extends ServiceImpl <UserMapper, User> implements IUserService {
    @Autowired
    private UserMapper userMapper;

    Map <Integer, User> map = new HashMap <>();

    /**
     * 缓存10秒钟
     */
    private Cache <Integer, User> guavaCache = CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build();


    @Override
    public DataResponse <List <User>> findByAll() {
        List <User> allUserList = userMapper.selectList(null);
        Integer allTotal = userMapper.selectCount(null);
        return DataResponse.BuildSuccessResponse(allUserList, allTotal);
    }


    @Override
    public DataResponse <Boolean> insertBatch(List <User> list) {
        if (null == list) {
            return DataResponse.BuildFailResponse("参数不能为空!");
        }
        boolean batchSave = this.saveBatch(list);
        return DataResponse.BuildSuccessResponse(batchSave);
    }

    @Transactional
    public DataResponse <Boolean> update(User user) {
        if (null == user || user.getId() == null) {
            return DataResponse.BuildFailResponse("必传参数不能为空!");
        }
        int update = userMapper.update(user);
        return DataResponse.BuildSuccessResponse(update > 0 ? true : false);
    }

    public DataResponse <User> findById(int i) {
        User byId = userMapper.findById(i);
        return DataResponse.BuildSuccessResponse(byId);
    }

    @Override
    public DataResponse <List <User>> findByPage(UserAO ao) {
        if (ao == null) {
            ao.setPage(0);
            ao.setPageSize(10);
        } else {
            ao.setPage(ao.getPageSize() * ao.getPage());
        }
        int allTotal = userMapper.findAllTotal();
        List <User> byPage = userMapper.findByPage(ao);
        return DataResponse.BuildSuccessResponse(byPage, allTotal);
    }

    @Override
    public User findLocalCacheById(Integer id) {
        if (null == id) {
            log.info("id为空!");
            return null;
        }
        boolean userExist = map.containsKey(id);
        if (userExist) {
            log.info("从缓存获取用户信息:{}", JSONObject.toJSONString(map.get(id)));
            return map.get(id);
        } else {
            User user = userMapper.findById(id);
            log.info("从数据库中获取用户信息{}", JSONObject.toJSONString(user));
            if (null != user) {
                map.put(id, user);
            }
            return user;
        }
    }

    @Override
    public User findGuavaCacheById(Integer id) {
        if (null == id) {
            log.info("获取guava缓存未传id！");
            return null;
        }
        User user = guavaCache.getIfPresent(id);
        if (user != null) {
            log.info("从guava缓存获取用户信息:{}", JSONObject.toJSONString(map.get(id)));
            return user;
        } else {
            user = userMapper.findById(id);
            log.info("从数据库中获取用户信息{}", JSONObject.toJSONString(user));
            if (null != user) {
                guavaCache.put(id, user);
            }
            return user;
        }
    }

    @Cacheable(value = "questionCreatedTrack", key = "#id", condition = "#id>0")
    @Override
    public User findSpringGuavaCacheById(Integer id) {
        if (null == id) {
            return null;
        }
        User user = userMapper.findById(id);
        log.info("从数据库中获取用户信息{}", JSONObject.toJSONString(user));
        return user;
    }

    /**
     * cacheNames 缓存名称
     * key 指定要清除的id
     * beforeInvocation =true 若为true则清除 cacheNames所有的缓存
     *
     * @param id
     */
    @CacheEvict(cacheNames = "questionCreatedTrack", key = "#id")
    @Override
    public void deleteCache(Integer id) {
        log.info("调用了清除缓存:" + id);
    }

    @Override
    public User findByUserId(Integer id) {
        return this.findSpringGuavaCacheById(id);
    }
}
